<script lang="ts" setup>
import { Ref } from 'vue'
import { merge } from 'lodash-es'
import { useECharts } from '../hooks/useECharts'
import type { PieSeriesOption, EChartsOption } from 'echarts'

const props = defineProps<{
  /** 图表数据 */
  data: PieSeriesOption['data']
  /** 配置项 */
  options?: EChartsOption
  /** 是否开启轮播 */
  isLoopPlay?: boolean
  /** 轮播间隔/ms */
  loopGap?: number
}>()
const emit = defineEmits<{
  (e: 'clickItem', val: object): void
}>()

/** 容器 */
const chartRef = ref<HTMLDivElement | null>(null)
/** 实例方法 */
const { setOptions, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
/** 计时器 */
let timer = shallowRef(0)

watchEffect(() => {
  /** 无数据则不绘制 */
  if (!props.data?.length) return

  /** 基本配置(在项目中使用时，修改成统一样式风格) */
  let basicOptions = {
    tooltip: {
      trigger: 'item'
    },
    series: [
      {
        name: '访问来源',
        type: 'pie',
        radius: '30%',
        center: ['50%', '50%'],
        color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
        data: props.data
      }
    ]
  } as EChartsOption

  /** 有传入的配置，则使用一个深度递归合并的配置 */
  if (props.options) {
    const { options } = props
    basicOptions = merge(basicOptions, options)
  }

  /** 绘制 */
  setOptions(basicOptions)

  /** 高亮项的下标 */
  const highlightIndex = ref(0)
  /** 图表实例 */
  const echartInstance = getInstance()

  /** 开启轮播 */
  function loopPlay() {
    const gap = props.loopGap ? props.loopGap : 2000
    /** 数据长度小于2不轮播 */
    if (!props.data?.length || props.data.length < 2) return
    timer.value = setInterval(() => {
      if (highlightIndex.value + 1 === props.data?.length) {
        highlightIndex.value = 0
      } else {
        highlightIndex.value++
      }
      highlightItem(highlightIndex.value)
    }, gap)
  }

  /** 轮播高亮某一项 */
  function highlightItem(dataIndex: number) {
    setTimeout(() => {
      echartInstance?.dispatchAction({
        type: 'downplay',
        seriesIndex: 0
      })
      echartInstance?.dispatchAction({
        type: 'highlight',
        dataIndex
      })
    }, 40)
  }

  /** 监听鼠标移入，停止轮播 */
  echartInstance?.on('mouseover', (p) => {
    const { dataIndex } = p
    if (timer.value) clearInterval(timer.value)
    echartInstance?.dispatchAction({
      type: 'downplay',
      seriesIndex: 0
    })
    echartInstance?.dispatchAction({
      type: 'highlight',
      dataIndex
    })
  })

  /** 监听鼠标移出，重新轮播 */
  echartInstance?.on('mouseout', (p) => {
    const { dataIndex } = p
    highlightIndex.value = dataIndex
    loopPlay()
  })

  /** 监听鼠标点击 */
  echartInstance?.on('click', (p) => {
    /** 将整个echarts事件参数回调出去 */
    emit('clickItem', p)
  })

  /** 初始轮播 */
  if (props.isLoopPlay) {
    loopPlay()
  }
})

onUnmounted(() => {
  if (timer.value) {
    clearInterval(timer.value)
    timer.value = 0
  }
})
</script>

<template>
  <div ref="chartRef" style="width: 100%; height: 100%"></div>
</template>
